#ifndef XML_H
#define XML_H

#include "tinyxml/tinyxml.h"


#include <string>

using std::string;
using std::wstring;

#define XMLVARIANT_MAKE_INT_PARA(type_size, radix) ((radix << 16) + type_size)
#define XMLVARIANT_MAKE_INT_PARA_DEF XMLVARIANT_MAKE_INT_PARA(sizeof(int), 10)

enum XmlVariantType{XVT_UNKNOWN = 0, 
				    XVT_INT,
					XVT_FLOAT,
					XVT_DOUBLE,
					XVT_BOOL,
					XVT_STDSTRING, 
					XVT_STDWSTRING,
					XVT_SYSTEMTIME};

typedef TiXmlDocument XmlDocument;
typedef TiXmlElement XmlElement;
typedef TiXmlAttribute XmlAttribute;

class Xml
{
public:
	Xml(void);
	~Xml(void);

	bool save(const wstring & file = L"");
	bool open(const wstring & file);

	static TiXmlElement * getElement(TiXmlElement * elem, const string & path, bool createElementIfNotExist = false);
	static void splitAttributePath(string & attribute, string & path, const string & fullPath);
	static bool setAttribute(TiXmlElement * elem, const string & attributePath, const wstring & value);
	static bool setAttribute(TiXmlElement * elem, const string & attributePath, int value);
	static bool setValue(TiXmlElement * elem, const string & path, const wstring & value);
	static bool setValue(TiXmlElement * elem, const string & path, int value, int radix = 10);
	static bool saveAttribute(const wstring & file, const string & path, const wstring & value);

	static bool getAttribute(const TiXmlElement * elem, const string & attributePath, wstring & value);
	static bool getAttribute(const TiXmlElement * elem, const string & attribute, void * value, size_t paraSize = sizeof(int), int radix = 10);
	static bool getValue(const TiXmlElement * elem, const string & path, wstring & value);
	static bool getValue(const TiXmlElement * elem, const string & path, void * value, size_t paraSize = sizeof(int), int radix = 10);
	static bool removeAllChild(TiXmlElement * elem);
	static void formatNodeName(string & name);

	TiXmlElement * getElement(const string & path, bool createElementIfNotExist = false);
	bool setAttribute(const string & attributePath, const wstring & value);
	bool setAttribute(const string & attributePath, int value);
	bool setValue(const string & path, const wstring & value);
	bool setValue(const string & path, int value, int radix = 10);

	bool getAttribute(const string & attributePath, wstring & value);
	bool getAttribute(const string & attributePath, void * value, size_t paraSize = sizeof(int), int radix = 10);
	bool getValue(const string & path, wstring & value);
	bool getValue(const string & path, void * value, size_t paraSize = sizeof(int), int radix = 10);
	XmlDocument & getDocument() { return mDoc; }
	void clear() { mDoc.Clear(); }
protected:
	static void setValueEx(XmlElement * elem, const wstring & value);
	static void setValueEx(XmlElement * elem, int value, int radix = 10);
private:
	XmlDocument mDoc;
	wstring mFile;
};

#endif